using System;
using UnityEngine;
using UnityEngine.UI;

namespace UnityX
{
    /// <summary>
    /// 剪裁图片显示成扇形带颜色渐变功能，开始结束角度以顺时针计算
    /// </summary>
    [DisallowMultipleComponent]
    [RequireComponent(typeof(CanvasRenderer))]
    [AddComponentMenu("UI/UnityX/Image Sector Gradient Color")]
    public class ImageSectorGradientColor : MaskableGraphic
    {
        [SerializeField]
        protected Texture m_Texture;

        [Range(-360, 360)]
        [SerializeField]
        protected float m_BeginAngle = 0;
        [Range(-360, 360)]
        [SerializeField]
        protected float m_EndAngle = 360;
        [Range(12, 360)]
        [SerializeField]
        protected int m_VertCount = 60;

        [SerializeField]
        protected Color m_BeginColor = Color.white;
        [SerializeField]
        protected Color m_EndColor = Color.white;
        [SerializeField]
        protected Color m_CenterColor = Color.white;

        public override Texture mainTexture
        {
            get
            {
                if (m_Texture == null)
                {
                    if (material != null && material.mainTexture != null)
                    {
                        return material.mainTexture;
                    }
                    return s_WhiteTexture;
                }
                return m_Texture;
            }
        }
        public Texture texture
        {
            get
            {
                return m_Texture;
            }
            set
            {
                if (m_Texture == value)
                    return;
                m_Texture = value;
                SetVerticesDirty();
                SetMaterialDirty();
            }
        }
        /// <summary>
        /// 开始结束角度以顺时针计算
        /// </summary>
        public float beginAngle { get => m_BeginAngle; set { m_BeginAngle = value; SetVerticesDirty(); } }
        /// <summary>
        /// 开始结束角度以顺时针计算
        /// </summary>
        public float endAngle { get => m_EndAngle; set { m_EndAngle = value; SetVerticesDirty(); } }
        public int vertCount { get => m_VertCount; set { m_VertCount = value; SetVerticesDirty(); } }
        public Color beginColor { get => m_BeginColor; set { m_BeginColor = value; SetVerticesDirty(); } }
        public Color endColor { get => m_EndColor; set { m_EndColor = value; SetVerticesDirty(); } }

        protected ImageSectorGradientColor()
        {
            useLegacyMeshGeneration = false;
        }
        protected override void OnDidApplyAnimationProperties()
        {
            SetMaterialDirty();
            SetVerticesDirty();
            SetRaycastDirty();
        }
        protected override void OnPopulateMesh(VertexHelper vh)
        {
            vh.Clear();

            //空圆
            if (m_BeginAngle >= m_EndAngle)
            {
                return;
            }

            Rect rect = GetPixelAdjustedRect();
            Color32 color = this.color;
            float rx = rect.width / 2;
            float ry = rect.height / 2;
            float cx = rect.x + rx;
            float cy = rect.y + ry;
            double gap = Math.PI * 2 / m_VertCount;
            //中心点
            vh.AddVert(new Vector3(cx, cy), color * m_CenterColor, new Vector2(0.5f, 0.5f));

            //满圆
            if (m_EndAngle - m_BeginAngle >= 360)
            {
                //外围点
                for (int i = 0; i < m_VertCount; i++)
                {
                    float x = (float)Math.Cos(i * gap);
                    float y = (float)Math.Sin(i * gap);
                    vh.AddVert(new Vector3(rx * x + cx, ry * y + cy), color * m_EndColor, new Vector2((x + 1) / 2, (y + 1) / 2));
                }
                //面
                for (int i = 1; i < m_VertCount; i++)
                {
                    vh.AddTriangle(0, i, i + 1);
                }
                vh.AddTriangle(0, m_VertCount, 1);
            }
            //非满圆
            else
            {
                double a1 = (m_BeginAngle - 90) * Math.PI / 180;
                double a2 = (m_EndAngle - 90) * Math.PI / 180;
                //外围点
                for (double i = a1; i < a2; i += gap)
                {
                    float v = (float)((i - a1) / (a2 - a1));
                    Color color1 = Color.Lerp(m_BeginColor, m_EndColor, v);

                    float x = (float)Math.Cos(i);
                    float y = -(float)Math.Sin(i);
                    vh.AddVert(new Vector3(rx * x + cx, ry * y + cy), color * color1, new Vector2((x + 1) / 2, (y + 1) / 2));
                }
                //最后一个点
                {
                    float x = (float)Math.Cos(a2);
                    float y = -(float)Math.Sin(a2);
                    vh.AddVert(new Vector3(rx * x + cx, ry * y + cy), color * m_EndColor, new Vector2((x + 1) / 2, (y + 1) / 2));
                }
                //面
                for (int i = 1; i < vh.currentVertCount - 1; i++)
                {
                    vh.AddTriangle(0, i, i + 1);
                }
            }
        }
    }
}